//
//  VHLSQLitePropertyModel.swift
//  VideoEditor_Swift
//
//  Created by Vincent on 2020/5/25.
//  Copyright © 2020 Darnel Studio. All rights reserved.
//

import UIKit
import SQLite3

/** sqlite 数据库支持的类型 */
public enum VHLSQLiteType: String {
    case INTEGER = "INTEGER"    // 整形
    case REAL = "REAL"          // 浮点数类型
    case TEXT = "TEXT"          // 文本类型
    case BLOB = "BLOB"          // 数据类型
    case NULL = "NULL"          // 没有值
}
/// 查询排序
public enum VHLSQLiteOrderBy {
    case ASC(String)            // 升序排列
    case DESC(String)           // 降序排列
    
    var sql: String {
        switch self {
        case .ASC(let name):
            return "`\(name)` ASC"
        case .DESC(let name):
            return "`\(name)` DESC"
        }
    }
    
    var keyName: String {
        switch self {
        case .ASC(let name):
            return name
        case .DESC(let name):
            return name
        }
    }
}

/**
 保存单个属性的 Model
 */
public class VHLSQLiteProperty: NSObject {
    /// 是否是主键
    public var isPrimaryKey: Bool = false
    /// 类型
    public var type: Any.Type       // 属性的类型
    
    public var key: String
    public var value: Any?
    
    public var isNull: Bool = true
    
    public init(type: Any.Type, key: String, value: AnyObject?, isPrimaryKey: Bool = false) {
        self.isPrimaryKey = isPrimaryKey
        self.type = type
        self.key = key
        self.value = value
    }
}

// MARK: - 扩展获取信息
extension VHLSQLiteProperty {
    /// sqlite 对应的类型
    public var sqlType: VHLSQLiteType {
        get {
            var sqlType: VHLSQLiteType = .NULL
            // 数字类型
            if type is Int.Type || type is Int?.Type {
                sqlType = .INTEGER
            }
            // Bool sqlite 没有单独的 Boolean
            if type is Bool.Type || type is Bool?.Type {
                sqlType = .INTEGER
            }
            // 浮点数类型
            else if type is Float.Type || type is Float?.Type ||
                        type is Double.Type || type is Double?.Type ||
                        type is CGFloat.Type || type is CGFloat?.Type {
                sqlType = .REAL
            }
            else if type is NSNumber.Type || type is NSNumber?.Type {
                sqlType = .REAL
            }
            // 文本类型
            else if type is NSString.Type || type is NSString?.Type ||
                type is String.Type || type is String?.Type ||
                type is Character.Type || type is Character?.Type {
                sqlType = .TEXT
            }
            // data 类型
            else if type is Data.Type || type is Data?.Type {
                sqlType = .BLOB
            }
            // date 日期类型
            else if type is Date.Type || type is Date?.Type {
                sqlType = .TEXT
            }
            else if sqlType == .NULL {
                VHLSQLitePrint("SQL type 不支持的类型:", key, type, sqlType)
            }
            
            return sqlType
        }
    }
    
    public var sqlValue: Any? {
        get {
            // 将 date 类型格式化存入数据库
            if (type is Date.Type || type is Date?.Type), let date = value as? Date {
                let dateString = VHLSQLiteTool.dateFormatter.string(from: date)
                return dateString as Any
            }
            return value
        }
    }
}

// MARK: - 转换数据类型，避免 Codable 错误
public extension VHLSQLiteProperty {
    // 转换值类型，比如数据库查出来是 Int，但是现在数据已经被改为 String，Codable 会错误。
    func transformValueType(_ value: Any) -> Any {
        // 字符串类型。但数据库之前存储是数值类型
        if type is NSString.Type || type is NSString?.Type ||
            type is String.Type || type is String?.Type ||
            type is Character.Type || type is Character?.Type {

            if let value = value as? Int {
                return String(value)
            } else if let value = value as? Float {
                return String(value)
            } else if let value = value as? Double {
                return String(value)
            }
        }
        
        // Bool 类型
        if type is Bool.Type || type is Bool?.Type {
            if let value = value as? Int {
                return value == 1
            }
        }
        
        return value
    }
}
